// JavaScript Document

var paneUI = {
	
    // stores a reference to the currently loaded article category for quick addition
    category_id: null,
	
    // stores a reference to the last selected category link
    lastCategoryLink: null,
	
    // parent ID of currently editted category
    lastCategoryParentID: null,
	
    // ajax page
    ajax_page : null,
	
    // the content type
    contentName : null,

    // items per page
    itemsPerPage: 25,
	
	// current page in the pagination
	current_page: 0,

    // paneUI editor state
    editorState: 'add',
	
    // the params
    params: null,
	
    init: function(params) {
		
        // store the passed parameters
        paneUI.params = params;
		
        // get the ajax_page parameter if it exists
        paneUI.ajax_page = params.ajax_page || null;
        paneUI.contentName = params.contentName || 'Items';

        // register the add category link
        $p('#add-cat-link').bind('click',function(){
            paneUI._showDialogForAdd();
        });
		
        // register the event listener for the add category link
        $p('#edit-cat-link').bind('click', function() {
            paneUI._showDialogForEdit();
        });

        // register the delete category link
        $p('#del-cat-link').bind('click', function() {
            paneUI.deleteCategory();
        });

        // register the cancel category dialog button
        $p('#cat-cancel-btn').bind('click', function() {
            paneUI.hideCategoryDialog();
        });

        // register the add item link
        $p('#add-link').bind('click', function() {
            paneUI.editorState = 'add';
            paneUI.loadItemEditor();
        });

        // register the delete item link
        $p('#delete-link').bind('click', function() {
            paneUI.deleteItems();
        });
		
        // register the category links
        $p(".category-list li a").bind("click",function(){
            //load the items in this category and indicate it as selected
            paneUI.loadItems(this);
            
            return false;
        });
		
        // create a UI Menu using the UI script framework
        var items_array = new Array();
        $p.all(".category-list li a", function(el, i) {
            var mi = {
                id: el.getAttribute("data-id"),
                name: el.innerHTML,
                title: el.title,

                // menus will call this action and supply the menu item as a parameter, so define the
                // action to use the supplied object
                action: function(mi) {
                    paneUI.moveToCategory( mi );
                }
            };

            items_array[i] = mi;
        });

        // convert the move link into a menu
        ui.menu( $p.$("#move-link"), {
            items: items_array
        });
		
        // load the items in the first category
        var firstCat = $p.$(".category-list li:first-child a");
        if( firstCat ) {
            paneUI.loadItems( firstCat );
        }
		
        // if the implementing class provides callback function for the category
        // add completion state, then call that function
        if( paneUI.params.onInitCompleted ) {
            paneUI.params.onInitCompleted();
        }
    },

    getCategoryLink: function(id) {
        return $p.$(".category-list li a#cat-" + id );
    },
	
    loadItems: function(catLink, page) {
		
        // if a category link is not specified, check if a previous one exists and use that instead
        if( catLink == null && paneUI.lastCategoryLink != null ) {
            catLink = paneUI.lastCategoryLink;
		
        // if one does not exist, then inform and exit
        } else if( catLink == null && paneUI.lastCategoryLink == null) {
            alert('Cannot Load ' + paneUI.contentName + ' If Category Link Is Not Specified');
            return;
        }
		
        // set a variable to determine the limit for the number of pages to load
        var limit = paneUI.params.itemsPerPage ? paneUI.params.itemsPerPage : paneUI.itemsPerPage;
		
        //clear any previously selected list items
        if( paneUI.lastCategoryLink != null ) {
            paneUI.lastCategoryLink.parentNode.className = '';
        }
		
        var catName = catLink.innerHTML;
        var catId = catLink.getAttribute("data-id");
        catLink.parentNode.className = 'selected';
		
        // cache the last category link
        paneUI.lastCategoryLink = catLink;
        // cache the currently selected category id
        paneUI.category_id = catId;
		
        // update the article list header
        document.getElementById("art-pane-header").innerHTML = paneUI.contentName + ' In ' + catName;

        // do the actual load process
        $p.setLoaderMessage("Loading Items In " + catName + ". Please Wait...");
        paneUI.runLoadItems(catId, limit, page);
    },

    runLoadItems: function(catId, limit, page) {
        // build the query to load the items based on the category id
        var query = "action=load_items";

        if( catId ) {
            query += "&category=" + catId;
        }

        if( limit ) {
            query += "&limit=" + limit;
        } else {
            limit = paneUI.params.itemsPerPage ? paneUI.params.itemsPerPage : paneUI.itemsPerPage;
			query += "&limit=" + limit;
        }

        // if a specific page is specified, then ammend the query to include that
        // also add the option to not reload the items-total data so that the navigation
        // bar would not be regenerated
        if( page ) {
            query += "&start=" + page + "&no-total=true";
			
			// cache the current page for later if this function is called without
			// specifying a page yet the pagination was previously used
			paneUI.current_page = page;
        }
		
		else if( paneUI.current_page ) {
			query += "&start=" + paneUI.current_page + "&no-total=true";
		}
		
        $p.post( paneUI.ajax_page, query, function(d) {
			$("#articles-display").html(d);
			
            // obtain the information about the total number of items in this category
            // and generate a dynamic list of page links
            if( document.getElementById("items-total") ) {
                
                var total = document.getElementById("items-total").value;
                var total_pages = Math.ceil((total / limit));

                // get the footer pane and clear the contents
                var paneFooter = $p(".articles-pane .pane-footer").node();
                paneFooter.innerHTML = "<b>Pages: </b> ";

                for(var i = 0; i < total_pages; i++) {
                    var a = document.createElement("a");
                    a.setAttribute("href","#");
                    a.id = "page-" + i;
                    a.className = "nav-link";

                    // if this is the first link, then indicate that this is the selected page
                    if( i == 0 ) {
                        a.className = "selected";
                    }

                    a.innerHTML = (i + 1);

                    // add the necessary callback to the link to enable page loading
                    a.onclick = function() {
                        $p.all(".pane-footer a", function(el) {
                            el.className = "nav-link";
                        });

                        this.className = "selected";

                        var p = this.id.split("-")[1];
						
						if( paneUI.lastCategoryLink ) {
							paneUI.loadItems( paneUI.lastCategoryLink, p);	
						} else {
							paneUI.runLoadItems(null, null, p);	
						}
                        
                    };

                    paneFooter.appendChild( a );
                }
            }

            // register the checkAll checkbox to be able to select all displayed messages
            $p.addEvent('checkAll', 'click', function() {

                // select all input fields in table-cells in the data-table component
                $p.all(".cms-data-table td input[type=checkbox]", function(el) {
                    el.checked = $p.$('checkAll').checked;
                });
            });

            // register all edit-links
            $p.all(".cms-data-table .edit-link", function(el) {
                el.onclick = function(e) {
                    paneUI.editItem( this.id );
                    return false;
                };
            });

            // register all edit-links
            $p.all(".cms-data-table .delete-link", function(el) {
                $p(el).bind('click', function(e) {
                    paneUI.deleteItem( this.id );
                    return false;
                });
            });

            // register all the publish or unpublish-links
            $p.all(".cms-data-table .cms-publish-link, .cms-data-table .cms-unpublish-link", function(el) {
                el.onclick = function() {
                    paneUI.publishItem( this );
                    return false;
                };
            });
        });

        // if the implementing class provides callback function for the category
        // add completion state, then call that function
        if( paneUI.params.onItemsLoaded ) {
            paneUI.params.onItemsLoaded();
        }
    },

    reloadItems: function() {
		if( paneUI.lastCategoryLink ) {
        	paneUI.loadItems( paneUI.lastCategoryLink );
		} else {
			paneUI.runLoadItems();
		}
    },
	
    publishItem: function(pubLink) {
        var shdPublish = pubLink.className == 'cms-publish-link' ? false : true;
		
        var query = "action=publish_item&item_id=" + pubLink.id + "&publish=" + shdPublish;
		
        $p.post( paneUI.ajax_page, query, function() {
            pubLink.className = shdPublish ? 'cms-publish-link' : 'cms-unpublish-link';
            pubLink.title = shdPublish ? 'Published (Click To Unpublish)' : 'Unpublished (Click To Publish Now)';

            // if the implementing class provides callback function for the item publish
            // completion state, then call that function
            if( paneUI.params.onItemPublished ) {
                paneUI.params.onItemPublished(shdPublish);
            }
        });
    },

    /**
     * Moves the selected Items to the specified category
     */
    moveToCategory: function(menuLink) {
        var selected = paneUI.getCheckedItems();

        if( selected.length == 0 ) {
            alert("Please Select " + paneUI.contentName + " To Be Moved");
            return;
        }

        var item_ids = "";
        for(var i = 0; i < selected.length; i++) {
            item_ids += selected[i].value;

            if( i < selected.length - 1 ) {
                item_ids += ",";
            }
        }

        var query = "action=move_items&category_id=" + menuLink.id + "&item_ids=" + item_ids;
		
        $p.post( paneUI.ajax_page, query, function(data) {
            //alert(data);
            paneUI.removeSelectedItems();
			
            // if the implementing class provides callback function for the category
            // move completion state, then call that function
            if( paneUI.params.onCategoryMoved ) {
                paneUI.params.onCategoryMoved();
            }
        });
    },

    deleteItem: function(item_id) {
        $p.showConfirmMessage({
            title: 'Confirm ' + paneUI.contentName +  ' Delete',
            content: "Do you want to delete the specified " + paneUI.contentName + " from this site?",
            okButtonText: 'Continue Delete',

            okButtonAction: function() {

                var query = "action=delete_items&item_ids=" + item_id;
                $p.post( paneUI.ajax_page, query, function(data) {
                    $p("#article-row-" + item_id ).remove();
                });
            }
        });
    },
	
    deleteItems: function() {
		
        /**
         * it would have been so much easier to use the following selector
         * .cms-data-table td input[type=checkbox]:checked
         * but IE8 does not support the :checked pseudo class, so we will need to
         * do the checking manually in order to be cross platform compartible
         */
        var checked = paneUI.getCheckedItems();
		
        if( checked.length == 0 ) {
            alert("Please Select Items To Delete");
            return;
        }
		
        $p.showConfirmMessage({
            title: "Confirm Delete Action",
            content: "Do you want to delete the selected " + paneUI.contentName + " from this site?",
            okButtonText: "Delete Selected",
            okButtonAction: function(e) {
                var boxes = $p.all(".cms-data-table tr td input[type=checkbox]");
                var selected = [];
				
                for(var i = 0, j = 0; i < boxes.length; i++) {
                    if( boxes[i].checked ) {
                        selected[j++] = boxes[i].value;
                    }
                }
				
                var query = "action=delete_items&item_ids=" + selected;
                $p.post( paneUI.ajax_page, query, function() {
                    for(var i = 0; i < selected.length; i++) {
                        $p("#article-row-" + selected[i] ).remove();
                    }
					
                    // if the implementing class provides callback function for the items delete
                    // completion state, then call that function
                    if( paneUI.params.onItemsDeleted ) {
                        paneUI.params.onItemsDeleted();
                    }
                });
            }
        });
    },
	
    getCheckedItems: function() {
        var checks = $p.all(".cms-data-table td input[type=checkbox]");

        var checked = [];
        for(var i = 0, j = 0; i < checks.length; i++ ){
            if( checks[i].checked ) {
                checked[j++] = checks[i];
            }
        }

        return checked;
    },

    /**
     * Removes the selected items from the table display
     */
    removeSelectedItems: function() {
        // select all checkbox fields in table-cells in the data-table component
        $p.all(".cms-data-table td input[type=checkbox]", function(el) {
            if( el.checked ) {
                $p.remove("#article-row-" + el.value );
            }
        });

        // if only header row remains, then add an instruction row
        if( $p.all(".cms-data-table tbody tr").length == 1 ) {

            var td = document.createElement("td");
            td.colSpan = 3;
            td.appendChild( document.createTextNode("No " + paneUI.contentName + " Available In This Category") );

            var tr = document.createElement("tr");
            tr.appendChild(td);

            var table = $p(".cms-data-table tbody").node();
            table.appendChild(tr);

        }
    },

    /**
     * Shows the category add dialog
     */
    _showDialogForAdd: function() {
        // add seo alias creator
        $("#CategoryName").friendurl({
            id:'CategoryAlias'
        });
		
        $p('#cat-add-dialog .cms-dialog-title').html("Add Category");
        $p.all("#cat-add-dialog input[type=text], #cat-add-dialog textarea", function(el) {
            el.value = "";
        });

        $p('#cat-add-btn').val('Add Category');
        var btn = document.getElementById("cat-add-btn");
        if( btn ) btn.onclick = paneUI.addCategory;

        // if the implementing class provides callback function for the items delete
        // completion state, then call that function
        if( paneUI.params.onCategoryDataLoaded ) {
            paneUI.params.onCategoryDataLoaded();
        }

        $p('#cat-add-dialog').show();
       
    },
	
    _showDialogForEdit: function() {
        // remove seo alias creator
        $("#CategoryName").unbind('keyup');
		
        var selected = paneUI.lastCategoryLink;
        var query = "action=load_category&category_id=" + selected.getAttribute('data-id');

        $p.post( paneUI.ajax_page,query, function(data) {
			
            var obj = $p.parseJSON(data);
			
            if( obj == null ) return;

            // the following are kept for compartibility sake with existing code
            // until a complete rework can be done for the areas that use the default
            // forms/category_form for the renderering
            $p("#CategoryName").val(obj.CategoryName);
            $p("#CategoryDescription").val(obj.CategoryDescription);
            $p("#CategoryAlias").val(obj.CategoryAlias);
            $p("#Position").val(obj.Position);
            $p("#ParentID").val(obj.ParentID);
            $p("#id").val(obj.id);
			
            $p('#cat-add-dialog .cms-dialog-title').html("Edit Category Information");
			
            paneUI.lastCategoryParentID = obj.ParentID;
            $p('#cat-add-btn').val("Save Changes");
            var btn = document.getElementById("cat-add-btn");
            if( btn ) btn.onclick = paneUI.updateCategory;
			
            // if the implementing class provides callback function for the items delete
            // completion state, then call that function
            if( paneUI.params.onCategoryDataLoaded ) {
                paneUI.params.onCategoryDataLoaded(obj);
            }
			
            $p('#cat-add-dialog').show();
        });
    },
	
    hideCategoryDialog: function() {
        $p('#cat-add-dialog').hide();
    },

    /**
     * Loads the item editor for the current content
     */
    loadItemEditor: function(item_id) {

        $p("#editor-pane .pane-header").html(paneUI.contentName + " Editor");

        var query = "action=load_editor&editor_state=" + paneUI.editorState + "&item_id=" + item_id;
        $p.post( paneUI.ajax_page, query, '#editor-pane #pane-content', function() {

            // hide the content pane and show the editor
            $p("#content-pane").css("display","none");
            $p("#editor-pane").css("display", "block");

            // if the implementing class provides callback function for the editor load
            // completion state, then call that function
            if( paneUI.params.onEditorLoaded ) {
                paneUI.params.onEditorLoaded();
            }
        });
    },

    /**
     * Hides the Item Editor display
     */
    hideItemEditor: function() {
        // hide the editor and show the content pane
        $p("#editor-pane").css("display", "none");
        $p("#content-pane").css("display","table");

        // if the implementing class provides callback function for the editor load
        // completion state, then call that function
        if( paneUI.params.onEditorUnloaded ) {
            paneUI.params.onEditorUnloaded();
        }
    },

    editItem: function(item_id) {
        paneUI.editorState = 'edit';
        paneUI.loadItemEditor(item_id);
    },

    /**
     * Runs the process of validating the Category Form and saving the data to database
     * to create a new category for the current content
     */
    addCategory: function() {
        
		var valid = $p("#cat-add-form").validate({
			"CategoryName": "Category Name - Required",
			"CategoryDesc": "Category Description",
			"CategoryTag": "Category Tag - Required"
		});
		
        if( !valid ) {
            return;
        }
		
        var query = "action=add_category&" + $p("#cat-add-form").serialize();
        $p.post( paneUI.ajax_page, query, function(data) {

            var obj = $p.parseJSON(data);
            if( obj == null ) {
                history.go(0);
                return;
            }
			
            var newObj = {
                id: obj.id,
                name: obj.CategoryName,
                title: obj.CategoryDescription
            };

            paneUI.addCategoryItem(newObj);
			
            document.getElementById("cat-add-form").reset();
            $p('#cat-add-dialog').hide();
			
            // if the implementing class provides callback function for the category
            // add completion state, then call that function
            if( paneUI.params.onCategoryAdded ) {
                paneUI.params.onCategoryAdded();
            }
            
        });
    },

    /**
     * Runs the process of validating the Category Form and validating the data to be
     * saved to the database to update the currently selected category item
     */
    updateCategory: function() {

		var valid = $p("#cat-add-form").validate({
			"CategoryName": "Category Name - Required",
			"CategoryDesc": "Category Description",
			"CategoryTag": "Category Tag - Required"
		});
		
        if( !valid ) {
            return;
        }

        var lastCat = paneUI.lastCategoryLink;

        var query = "action=update_category&category_id=" + lastCat.getAttribute("data-id") + "&" + $p("#cat-add-form").serialize();

        $p.post( paneUI.ajax_page, query, function(data) {

            // retrieve the menu object information and update the link information
            // incase the titles or descriptions have been changed
            if(JSON) {

                var obj = $p.parseJSON(data);

                lastCat = paneUI.lastCategoryLink;
                lastCat.title = obj.CategoryDescription;
                lastCat.innerHTML = obj.CategoryName;

                // if the new Parent ID is not the same as the last parent ID before
                // the update, then attempt a repositioning
                if( paneUI.lastCategoryParentID != obj.ParentID ) {
                    var li = lastCat.parentNode;

                    if( obj.ParentID && obj.ParentID != "" ) {
                        // find the new parent element
                        $p.$(".category-list #cat-li-" + obj.ParentID).appendChild(li);
                    } else {
                        $p.$(".category-list").appendChild(li);
                    }
                }

            } else {
                history.go(0);
            }

            document.getElementById("cat-add-form").reset();

            // on ajax return hide
            $p("#cat-add-dialog").hide();

            // if the implementing class provides callback function for the category
            // udpate completion state, then call that function
            if( paneUI.params.onCategoryUpdated ) {
                paneUI.params.onCategoryUpdated();
            }
        });
    },
	
    deleteCategory: function() {
        
        var lastCat = paneUI.lastCategoryLink;
        var last_li = lastCat.parentNode;

        $p.showConfirmMessage({
            title: "Confirm Category Delete",
            content: "This will delete all articles in the <b>" + lastCat.innerHTML + "</b> category. "
            + "Do you want to continue the delete of this category?",
            width: '400px',
            okButtonText: "Delete Category",
            okButtonAction: function() {
                
                var query = "action=delete_category&category_id=" + lastCat.getAttribute("data-id") ;

                $p.post( paneUI.ajax_page, query, function() {
                    last_li.parentNode.removeChild( last_li );

                    // if the implementing class provides callback function for the category
                    // udpate completion state, then call that function
                    if( paneUI.params.onCategoryDeleted ) {
                        paneUI.params.onCategoryDeleted();
                    }
                });
            }
        });
    },
	
    /**
	 * Adds an item to the list of categories. The expected JS object should contain
	 * - name: the name of the item
	 * - title: a title or description
	 * - id: the database record id of the object
	 */
    addCategoryItem: function(obj) {

        if( typeof obj != "object" ) {
            return;
        }
		
        var a = document.createElement("a");
        a.id = obj.id;
        a.title = obj.title;
        a.setAttribute("href","#");
        a.setAttribute("data-id", obj.id );
        a.innerHTML = obj.name;
        a.onclick = function() {
            //clear any previously selected list items
            $p.all(".category-list li", function(li) {
                li.className = '';
            });
				
            // load the articles in this category and indicate it as selected
            paneUI.loadItems( this );
				
            return false;
        };
			
        var li = document.createElement("li");
        li.id = "cat-li-" + obj.id;
        li.appendChild(a);
			
        // if category has a parent
        if( obj.ParentID && obj.ParentID != '' ) {
            // check if parent has any children loaded
            var ul = $p.$(".category-list #cat-li-" + obj.ParentID + " ul" );
            // if a child list exists, simply append new item to list
            if( ul ) {
                ul.appendChild(li);
				
            // create the child list, append the new child, and append the list to the parent
            } else {
                ul = document.createElement("UL");
                ul.appendChild(li);
					
                $p.$(".category-list #cat-li-" + obj.ParentID ).appendChild(ul);
            }
			
        // if no parent, then append new item to main list
        } else {
            $p.$(".category-list").appendChild(li);
        }
    }
};